package com.hoozhi.common.web.hibernate;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;

/**
 * 定义对数据库增删改查操作的模版
 * @author pharen
 *
 * @param <T>
 * @param <PK>
 */
public class HibernateSimpleDao<T, PK extends Serializable> {
	
	private HibernateTemplate hibernateTemplate;

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}
	
	@Autowired
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
	
	/**
	 * 单语句执行查询
	 * @param queryString 传入的查询语句
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> createQuery(final String queryString) {
		return getHibernateTemplate().find(queryString);
	}
	
	/**
	 * 结合参数查询，使用'?'号通配符
	 * @param queryString    传入的查询语句
	 * 各'?'号通配符的具体值，
	 * 可用 obj1,obj2,obj3...对应各个参数的方式传入，
	 * 也可用 obj[] 数组的方式传入
	 * @param value   
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> createQuery(final String queryString, final Object ... value) {
		return getHibernateTemplate().find(queryString, value);
	}
	
	/**
	 * 使用命名查询
	 * @param queryString 查询语句 
	 * @param paramName 替换的名字
	 * @param value 具体值
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> findByNamedParam(String queryString, String paramName, Object value) {
		return getHibernateTemplate().findByNamedParam(queryString, paramName, value );
	}
	
	/**
	 * 带多个参数的命名查询
	 * @param queryString 查询语句
	 * @param paramMap 带有KEY(替换名字)-VALUE的 MAP
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<T> findByNamedParam(final String queryString, final Map paramMap){
		return getHibernateTemplate().findByNamedParam(queryString, (String[]) paramMap.keySet().toArray(new String[0]), paramMap.values().toArray() );
	}
	
	/**
	 * 执行SQL语句
	 * @param sql
	 * @return
	 */
	public int excuteSQL(String sql) {
		try {
			return getHibernateTemplate().bulkUpdate(sql);
		} catch (RuntimeException re) {
			re.printStackTrace();
			throw re;
		}
	}
	/**
	 * 传入MAP，执行带命名的SQL语句
	 * @param sql
	 * @param value
	 * @return
	 */
	public int excuteSQLByMap(final String queryString, final Map<String, Object> paraMap) {
		try {
			return (int) getHibernateTemplate().execute(new HibernateCallback<Integer>() {
				public Integer doInHibernate(Session session) throws HibernateException {
					Query queryObject = session.createQuery(queryString);
					if (paraMap != null) {
						Iterator<String> it = paraMap.keySet().iterator();
						while (it.hasNext()) {
							Object key = it.next();
							if( paraMap.get(key) instanceof Object[]){
								queryObject.setParameterList(key.toString(), (Object[])paraMap.get(key));
							}else {
								queryObject.setParameter(key.toString(), paraMap.get(key));
							}
						}
					}
					return queryObject.executeUpdate();
				}
			});
		} catch (RuntimeException re) {
			re.printStackTrace();
			throw re;
		}
	}
	/**
	 * 传入参数，执行带通配符的SQL语句
	 * @param sql
	 * @param value
	 * @return
	 */
	public int excuteSQL(String sql, Object ... value) {
		try {
			return getHibernateTemplate().bulkUpdate(sql, value);
		} catch (RuntimeException re) {
			re.printStackTrace();
			throw re;
		}
	}
}
